// 公共数据结构定义
#pragma once
#include <string>
#include <vector>
#include <unordered_map>
#include <variant>
#include <memory>
#include <set>
#include <optional>
#include <cstdint>
#include "nlohmann/json.hpp"

using json = nlohmann::json;
// 定义底层支持的数据类型集合
// 使用 std::string 来存储 DATE, TIME, DATETIME, 因为ISO 8601格式
// (例如 "YYYY-MM-DD HH:MM:SS") 的字符串可以进行正确的字典序排序。
using ValueType = std::variant<
    bool,       // 对应 BOOLEAN
    uint8_t,    // 对应 TINYINT UNSIGNED
    uint16_t,   // 对应 SMALLINT UNSIGNED
    uint32_t,   // 对应 INT UNSIGNED
    uint64_t,   // 对应 BIGINT UNSIGNED
    int8_t,     // 对应 TINYINT
    int16_t,    // 对应 SMALLINT
    int32_t,    // 对应 INT
    int64_t,    // 对应 BIGINT
    float,      // 对应 FLOAT
    double,     // 对应 DOUBLE
    std::string // 对应 VARCHAR, CHAR, TEXT, DATE, TIME, DATETIME, JSON, BLOB
    >;

// 定义最终的 Value 类型
// std::optional 用于原生表示可空性。
// 一个包含 std::nullopt 的 Value 对象即为 SQL 中的 NULL。
using Value = std::optional<ValueType>;
// B+树的键也使用相同的类型
using BPlusTreeKey = Value;

// 4. 为 Value 重载 operator< 以便用于 std::set 和 B+树的键
inline bool operator<(const Value &lhs, const Value &rhs)
{
    // 规则 1: 处理 NULL。我们定义 NULL 小于任何非 NULL 值。
    if (!lhs.has_value() && !rhs.has_value())
        return false; // 两个 NULL 相等
    if (!lhs.has_value())
        return true; // 左值为 NULL，右值非 NULL -> 左值更小
    if (!rhs.has_value())
        return false; // 右值为 NULL，左值非 NULL -> 左值不更小

    // 规则 2: 两个值都非 NULL。
    // 我们可以直接依赖 std::variant 的默认 operator<。
    // 它会首先按类型索引比较，如果类型相同，再按值比较。
    // 这为B+树提供了所需的一致的、完全的排序。
    return lhs.value() < rhs.value();
}

// 辅助函数：尝试将 ValueType 转换为 double
// 如果 variant 内部是数值或可解析的字符串，则返回 double，否则返回 nullopt
inline std::optional<double> valueToDouble(const ValueType &val)
{
    return std::visit([](auto &&arg) -> std::optional<double>
                      {
                          using T = std::decay_t<decltype(arg)>;
                          if constexpr (std::is_arithmetic_v<T>)
                          {
                              return static_cast<double>(arg); // 所有数值类型直接转换
                          }
                          else if constexpr (std::is_same_v<T, std::string>)
                          {
                              try
                              {
                                  return std::stod(arg); // 字符串尝试用 stod 转换
                              }
                              catch (const std::exception &)
                              {
                                  return std::nullopt; // 转换失败
                              }
                          }
                          return std::nullopt; // 其他类型无法转换
                      },
                      val);
}

// 辅助函数，用于比较两个 BPlusTreeKey (Value)
// 返回值:
//   -1: lhs < rhs
//    0: lhs == rhs
//    1: lhs > rhs
inline int compareKeys(const BPlusTreeKey &lhs, const BPlusTreeKey &rhs)
{
    // 规则 1: 处理 NULL
    if (!lhs.has_value() && !rhs.has_value())
        return 0; // NULL == NULL
    if (!lhs.has_value())
        return -1; // NULL < non-NULL
    if (!rhs.has_value())
        return 1; // non-NULL > NULL

    const auto &l_val = lhs.value();
    const auto &r_val = rhs.value();

    // 规则 2: 尝试将双方都作为数值进行比较
    std::optional<double> l_double_opt = valueToDouble(l_val);
    std::optional<double> r_double_opt = valueToDouble(r_val);

    // 如果双方都能成功转换为 double，则进行数值比较
    if (l_double_opt.has_value() && r_double_opt.has_value())
    {
        double l_double = l_double_opt.value();
        double r_double = r_double_opt.value();

        constexpr double epsilon = 1e-9;
        if (std::abs(l_double - r_double) < epsilon)
        {
            return 0;
        }
        if (l_double < r_double)
        {
            return -1;
        }
        return 1;
    }

    // 规则 3: 如果不能都作为数值比较，则退回到字符串比较
    // 适用于 (string, string), (string, uncastable_numeric_as_string), etc.
    // 这是一个更符合SQL通用行为的健壮回退策略
    std::string l_str = std::visit([](auto &&arg)
                                   { std::stringstream ss; ss << arg; return ss.str(); }, l_val);
    std::string r_str = std::visit([](auto &&arg)
                                   { std::stringstream ss; ss << arg; return ss.str(); }, r_val);

    if (l_str < r_str)
        return -1;
    if (l_str > r_str)
        return 1;

    // 如果字符串表示也相同，则它们相等
    return 0;
}

// -------------------------- 1. 元数据结构 --------------------------
// 列结构（对应接口的schema.columns）
struct ColumnSchema
{
    std::string name;                         // 列名
    std::string type;                         // 类型："INT" / "VARCHAR" / "BIGINT" / "DOUBLE" etc.
    int length;                               // 长度
    bool nullable = true;                     // 是否可空
    bool unique = false;                      // 是否唯一
    bool primary = false;                     // 是否主键
    bool auto_increment = false;              // 是否自增
    std::optional<std::string> default_value; // 默认值
    std::string comment;                      // 注释
};

// 索引结构（对应接口的schema.indexes）
struct IndexSchema
{
    std::string index_name;
    std::vector<std::string> columns; // 索引包含的列
    bool is_unique;                   // 是否唯一索引
    uint32_t root_page_id;            // 索引的根页ID（B+树实现）
};
// 表结构（对应接口的schema）
struct TableSchema
{
    std::string table_name;                                              // 表名
    std::vector<ColumnSchema> cols;                                      // 列列表
    uint32_t primary_page_id;                                            // 表的主键索引页ID
    std::vector<IndexSchema> indexes;                                    // 索引列表
    std::unordered_map<std::string, int64_t> auto_increment_counters;    // 自增列当前值
    std::unordered_map<std::string, std::set<Value>> unique_constraints; // 唯一约束
    std::string comment;                                                 // 表注释
    std::string primary_key_name;                                        // 主键索引名称
};

// -------------------------- 2. 执行计划结构（算子树） --------------------------
// 算子类型
enum class OpType
{
    SeqScan,     // 全表扫描
    Filter,      // 条件过滤
    Project,     // 列投影
    CreateTable, // 创建表
    Insert,      // 插入数据
    CreateIndex, // 创建索引
    DropIndex,   // 删除索引
    Update,      // 更新数据
    Delete,      // 删除数据
    DropTable,   // 删除表
    AlterTable,  // 修改表
    ShowTables,  // 显示所有表
    ShowIndices, // 显示表的所有索引
};

enum class ConditionType
{
    SIMPLE,
    AND,
    OR
};

// 代表查询条件的树节点
struct Condition
{
    ConditionType type;
    // --- 当 type == SIMPLE 时使用 ---
    std::string column; // 左侧列名
    std::string op;     // 操作符, e.g., "=", ">", "<", "!="
    Value value;        // 右侧值
    // --- 当 type == AND 或 OR 时使用 ---
    // 存储子条件，AND 或 OR 节点可以有多个子条件
    std::vector<std::unique_ptr<Condition>> children;
    Condition() = default;
    Condition(ConditionType type) : type(type) {}
    // 判断当前 Condition 是否为空（无实际条件）
    bool isEmpty() const
    {
        switch (type)
        {
        case ConditionType::SIMPLE:
            // 简单条件：列名、操作符、值任一为空则视为空条件
            return column.empty() || op.empty();

        case ConditionType::AND:
        case ConditionType::OR:
            // 复合条件：子条件为空，或所有子条件都为空
            if (children.empty())
            {
                return true;
            }
            // 检查所有子条件是否都为空（递归判断）
            for (const auto &child : children)
            {
                if (!child->isEmpty())
                {
                    // 只要有一个子条件非空，则当前复合条件非空
                    return false;
                }
            }
            // 所有子条件都为空，则当前复合条件为空
            return true;

        default:
            // 未知类型视为空条件
            return true;
        }
    }
};

struct ModifiedColumn
{
    std::optional<std::string> name = std::nullopt;
    std::optional<std::string> type = std::nullopt;
    std::optional<int> length = std::nullopt;
    std::optional<bool> nullable = std::nullopt;
    std::optional<bool> unique = std::nullopt;
    std::optional<bool> primary = std::nullopt;
    std::optional<bool> auto_increment = std::nullopt;
    std::optional<std::string> default_value = std::nullopt;
    std::optional<std::string> comment = std::nullopt;
};
struct OrderBy
{
    std::optional<std::string> order_by = std::nullopt;
    std::optional<std::string> order_type = std::nullopt;
    std::optional<uint16_t> seed = std::nullopt;
};
// 执行计划节点（递归结构，子节点用unique_ptr管理）
struct ExecutionPlanNode
{
    OpType op_type; // 算子类型
    // 算子详情（根据op_type动态填充）
    struct
    {
        std::string table_name;                                                                      // 所有
        Condition condition;                                                                         // 仅Filter,Delete,Update使用
        std::vector<std::string> project_cols;                                                       // 仅Project使用
        std::optional<uint16_t> offset = std::nullopt;                                               // 偏移量，仅project使用
        std::optional<uint16_t> limit = std::nullopt;                                                // 数量，仅project使用
        std::vector<OrderBy> order_by;                                                               // 排序规则
        std::unordered_map<std::string, Value> insert_values;                                        // 仅Insert使用
        std::vector<ColumnSchema> create_cols;                                                       // 仅CreateTable使用
        std::string create_comment;                                                                  // 仅CreateTable使用
        std::string index_name;                                                                      // 仅CreateIndex使用
        std::vector<std::string> index_columns;                                                      // 仅CreateIndex使用
        bool is_unique;                                                                              // 仅CreateIndex使用
        std::unordered_map<std::string, Value> update_values;                                        // 仅Update使用
        std::optional<std::string> rename_table_name = std::nullopt;                                 // 仅AlterTable使用(修改之后的表的名字)
        std::optional<std::string> modified_comment = std::nullopt;                                  // 仅AlterTable使用(修改之后的表注释)
        std::optional<std::unordered_map<std::string, ModifiedColumn>> modified_cols = std::nullopt; // 仅AlterTable使用(修改之后的列信息,key为原列名)
        std::optional<std::unordered_map<std::string, std::string>> modified_indexes = std::nullopt; // 仅AlterTable使用(修改之后的索引信息,key为原索引名,value为修改之后的索引名)
        std::optional<std::vector<std::string>> drop_cols = std::nullopt;                            // 仅AlterTable使用(删除的列名)
        std::optional<std::vector<ColumnSchema>> add_cols = std::nullopt;                            // 仅AlterTable使用(新增的列)
    } details;
    std::unique_ptr<ExecutionPlanNode> child; // 子算子（如Project→Filter→SeqScan）
};

// -------------------------- 3. 接口返回结果结构 --------------------------
// SQL编译器返回结果（对应compile接口的success/error）
struct CompileResult
{
    std::string status;                      // "success" / "error"
    std::unique_ptr<ExecutionPlanNode> plan; // 成功时的执行计划
    // 错误信息（仅status="error"时有效）
    struct
    {
        std::string error_type; // "Lexical Error" / "Syntax Error" / "Semantic Error"
        std::string message;    // 错误描述
        int line;               // 错误行号
        int column;             // 错误列号
    } error;
};

// 存储系统返回结果（对应allocate_page/get_page/write_page接口）
struct StorageResult
{
    std::string status;             // "success" / "error"
    uint32_t page_id;               // 仅allocate_page成功时有效
    std::vector<uint8_t> page_data; // 仅get_page成功时有效
    std::string message;            // 错误描述（仅status="error"时有效）
};

enum class QueryType
{
    SELECT,
    CREATE_TABLE,
    CREATE_INDEX,
    INSERT,
    UPDATE,
    DELETE,
    SHOW_TABLES,
    SHOW_INDICES,
    DROP_TABLE,
    DROP_INDEX,
    ALTER
};

// 数据库系统对外返回结果（对应execute_sql接口）
struct QueryResult
{
    std::string status; // "success" / "error"
    QueryType type = QueryType::SELECT;
    std::vector<std::string> columns;                                   // 成功时的列名（仅SELECT有效）
    std::vector<std::vector<Value>> rows;                               // 成功时的行数据（仅SELECT有效）
    std::unordered_map<std::string, std::vector<ColumnSchema>> schemas; // 仅show tables有效
    std::vector<IndexSchema> indexes;
    // 错误信息（仅status="error"时有效）
    std::string error_type;
    std::string message;
};

// 前向声明，因为 toJson(QueryResult) 会用到 fromJson(json) 的辅助函数 fromJsonValue
inline QueryResult fromJson(json j);

// 将单个 Value 序列化为 JSON
inline json toJson(const Value &value)
{
    // 如果 optional 为空 (即 SQL NULL)，返回 JSON null
    if (!value.has_value())
    {
        return nullptr;
    }

    // 否则，访问 variant 内部的值并将其转换为 JSON
    // nlohmann::json可以直接从 bool, 数字, string 等类型构造
    return std::visit(
        [](auto &&arg) -> json
        {
            return json(arg);
        },
        value.value());
}

// 将完整的 QueryResult 序列化为 JSON
inline json toJson(QueryResult result)
{
    json j;
    j["status"] = result.status;
    j["type"] = result.type;
    for (auto &col : result.columns)
    {
        j["columns"].push_back(col);
    }
    for (auto &row : result.rows)
    {
        json j_row = json::array();
        for (auto &val : row)
        {
            // 使用新的 Value->JSON 辅助函数
            j_row.push_back(toJson(val));
        }
        j["rows"].push_back(j_row);
    }
    for (auto &[schema_name, columns] : result.schemas)
    {
        json j_schema = json::object();
        j_schema["schema_name"] = schema_name;
        json j_columns = json::array();
        for (auto &col : columns)
        {
            json j_col = json::object();
            j_col["name"] = col.name;
            j_col["type"] = col.type;
            j_col["nullable"] = col.nullable;
            j_col["primary"] = col.primary;
            j_col["unique"] = col.unique;
            j_col["auto_increment"] = col.auto_increment;
            if (col.default_value.has_value())
            {
                j_col["default_value"] = col.default_value.value();
            }
            if (!col.comment.empty())
            {
                j_col["comment"] = col.comment;
            }
            j_columns.push_back(j_col);
        }
        j_schema["columns"] = j_columns;
        j["schemas"].push_back(j_schema);
    }
    for (auto &index : result.indexes)
    {
        json j_index = json::object();
        j_index["index_name"] = index.index_name;
        json j_columns = json::array();
        for (auto &col : index.columns)
        {
            j_columns.push_back(col);
        }
        j_index["columns"] = j_columns;
        j_index["is_unique"] = index.is_unique;
        j_index["root_page_id"] = index.root_page_id;
        j["indexes"].push_back(j_index);
    }
    j["error_type"] = result.error_type;
    j["message"] = result.message;
    return j;
}

// 从单个 JSON 值反序列化为 Value
inline Value fromJsonValue(const json &j)
{
    if (j.is_null())
    {
        return std::nullopt;
    }
    if (j.is_boolean())
    {
        return ValueType(j.get<bool>());
    }
    if (j.is_number_integer())
    {
        // 优先转为最大的整数类型以保证兼容性
        return ValueType(j.get<int64_t>());
    }
    if (j.is_number_float())
    {
        return ValueType(j.get<double>());
    }
    if (j.is_string())
    {
        return ValueType(j.get<std::string>());
    }
    // 对于不支持的JSON类型（如 object, array），返回 NULL
    return std::nullopt;
}

// 从 JSON 反序列化为完整的 QueryResult
inline QueryResult fromJson(json j)
{
    QueryResult result;
    result.status = j["status"];
    result.type = j["type"];
    for (auto &col : j["columns"])
    {
        result.columns.push_back(col);
    }
    for (auto &row : j["rows"])
    {
        std::vector<Value> row_values;
        for (auto &col_json : row)
        {
            // 使用新的 JSON->Value 辅助函数
            row_values.push_back(fromJsonValue(col_json));
        }
        result.rows.push_back(row_values);
    }
    for (auto &schema : j["schemas"])
    {
        std::string schema_name = schema["schema_name"];
        std::vector<ColumnSchema> columns;
        for (auto &col : schema["columns"])
        {
            ColumnSchema col_schema;
            col_schema.name = col["name"];
            col_schema.type = col["type"];
            col_schema.nullable = col["nullable"];
            col_schema.primary = col["primary"];
            col_schema.unique = col["unique"];
            col_schema.auto_increment = col["auto_increment"];
            if (col.contains("default_value"))
            {
                col_schema.default_value = col["default_value"];
            }
            if (col.contains("comment"))
            {
                col_schema.comment = col["comment"];
            }
            columns.push_back(col_schema);
        }
        result.schemas[schema_name] = columns;
    }
    for (auto &index : j["indexes"])
    {
        IndexSchema index_schema;
        index_schema.index_name = index["index_name"];
        for (auto &col : index["columns"])
        {
            index_schema.columns.push_back(col);
        }
        index_schema.is_unique = index["is_unique"];
        index_schema.root_page_id = index["root_page_id"];
        result.indexes.push_back(index_schema);
    }
    result.error_type = j["error_type"];
    result.message = j["message"];
    return result;
}